(function(){
   class DoublyNode{
       constructor(data){
           this.data = data
           this.prev = null;
           this.next = null
       }
   }

   class DoublyLinkedList{
       constructor(){
           this.head = null;
           this.tail = null;
           this.length = 0 
       }

       append(data){
         let newNode = new DoublyNode(data);
         if(this.length == 0){
             this.head = newNode;
             this.tail = newNode;
         }
         if(this.length>0){
             newNode.prev = this.tail;
             this.tail.next = newNode;
             this.tail = newNode;         
         }
         this.length+=1
       }

       forwardString(){
          let temStr = "";
          let current = this.head;
          while(current){
             temStr += current.data;
             current = current.next
          }
          return temStr
       }

       backwardString(){
           let temStr = "";
           let current = this.tail
           while(current){
            temStr += current.data;
            current = current.prev
         }
         return temStr        
       }

       toString(){
           return this.forwardString()
       }

       insert(position,data){
        if( position<0 || position>this.length )return false    

        let newNode = new DoublyNode(data);
        if(this.length == 0){
            this.head = newNode;
            this.tail = newNode;
        }else{
            if(position === 0){
                newNode.next = this.head;
                this.head.prev = newNode;
                this.head = newNode;
            }else if(position === this.length){
                newNode.prev = this.tail;
                this.tail.next =  newNode;
                this.tail = newNode
            }else{
                let current = this.head;
                let index = 0;
                while(index < position){
                    current = current.next;
                    index++
                }
                newNode.prev = current.prev;
                newNode.next = current;
                current.prev.next = newNode;
                current.prev   = newNode 
            }

        }
        this.length+=1
        return this
       }
       
       get(position){
        if( position < 0 || position >= this.length ){return null}      
        let current = this.head;
        let index = 0;

        while(index < position){
            current = current.next;
            index++
        }
        return current.data    
       }

       indexOf(data){
            let current = this.head;
            let index = 0;      
            while(current.data != data){
                if(current.next === null){
                    return -1
                }
                current = current.next;
                index++
            }
            return index

       }

       update(position,data){
        if( position<0 || position>=this.length )return false    

           let current = this.head;
           let index = 0
           while(index < position){
               current = current.next
               index+=1 ;
           }
           current.data = data;
           return true

       }

       removeAt(position){
          if( position < 0 || position >= this.length ){return null}
           
          let delNode = null
          if(this.length === 1){
              delNode = this.head
              this.head = null;
              this.tail = null;
          }else{
              if(position === 0){
                   delNode = this.head          
                   this.head = this.head.next 
                   this.head.prev = null
              }else if(position === this.length-1){
                    delNode = this.tail
                    this.tail = this.tail.prev;
                    this.tail.next = null
              }else{
                 let currrent = this.head;
                 let index = 0;
                 while(index <　position){
                    currrent = currrent.next;
                    index+=1
                }
                delNode = currrent
                currrent.prev.next = currrent.next;
                currrent.next.prev = currrent.prev;                 
              }
          }
          this.length-=1;
          return delNode.data
       }

       remove(data){
          let index =  this.indexOf(data);
          return this.removeAt(index)
       }

       isEmpty(){
           return this.length === 0? true:false
       }

       size(){
           return this.length
       }
   }



})()